#include "stdafx.h"
//-------------------------------------------------------------------------------------------------
//USBitMap.cpp  - Ultrasound Bitmap       
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2011
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------

#include <iostream>
#include <fstream>

#include "USBitMap.h"

USBitMap::~USBitMap(void)
{
	if ( _bitmapPixels != NULL)
		free(_bitmapPixels);
}

USBitMap::USBitMap(void)
{
	BYTE *pInit = (BYTE *) &_bitmapFileHeader;
	int HeaderSize = sizeof(BITMAPFILEHEADER);
	for (int x = 0; x < HeaderSize; x++)
		*(pInit+x) = 00;

	pInit = (BYTE *) &_bitmapInfoHeader;
	HeaderSize = sizeof(BITMAPINFOHEADER);
	for (int x = 0; x < HeaderSize; x++)
		*(pInit+x) = 00;
	
	_bitmapPixels = NULL;
	_BitMapPixelCnt = 0;
	_DicomRef = L"";

}

USBitMap::USBitMap(DicomPart *pPixelData, int Width, int Height)
{
	BYTE *pInit = (BYTE *) &_bitmapFileHeader;
	int HeaderSize = sizeof(BITMAPFILEHEADER);
	for (int x = 0; x < HeaderSize; x++)
		*(pInit+x) = 00;

	pInit = (BYTE *) &_bitmapInfoHeader;
	HeaderSize = sizeof(BITMAPINFOHEADER);
	for (int x = 0; x < HeaderSize; x++)
		*(pInit+x) = 00;

	_bitmapPixels = NULL;
	_BitMapPixelCnt = 0;
	_DicomRef = L"";
	
	if ( pPixelData->GetDataLength() == (Width * Height * 3))
	{
		int padcnt = Width % 4;											//pixel format RGB=8.8.8
		_BitMapPixelCnt = ((Width * 3) + padcnt) * Height;		

		_bitmapPixels = (BYTE *) malloc( _BitMapPixelCnt + 1);
		_bitmapPixels[_BitMapPixelCnt] = 0xCC;

		BYTE *pBitMapPixel = _bitmapPixels + _BitMapPixelCnt - 1;		//start at bottom line, subtract one because arrays have zero based count and _BitMapPixelCnt is one based
		BYTE *pDicomPixel = pPixelData->GetFirstDataByte();
		BYTE red = 0x00;
		BYTE green = 0x00;
		BYTE blue = 0x00;

		long pixelCnt = 0;
		for (int y = 0; y < Height; y++ )
		{
			*pBitMapPixel = 0xFF;										//end of line marker, this will be overwritten by padding or pixel data
			for (int padding = 0; padding < padcnt; padding++)			//add padding to end of line
			{
				*pBitMapPixel = 0x00;
				pBitMapPixel--;
			}
			pBitMapPixel -= (Width * 3) + padcnt - 1;					//fill from the start of line
			for (int x = 0; x < Width - padcnt; x++ )					
			{
				blue = *pDicomPixel++;
				green = *pDicomPixel++;
				red = *pDicomPixel++;

				*pBitMapPixel++ = red;	
				*pBitMapPixel++ = green;	
				*pBitMapPixel++ = blue;	
			}
			pBitMapPixel += padcnt;										//move to end of line
			pBitMapPixel -= (Width * 3) + padcnt + 1;					//move to end of previous line
		}
		pBitMapPixel += 1;												//move back to start of next line - i.e. last line in bitmap (top, left)
		if ( (_bitmapPixels[_BitMapPixelCnt] == 0xCC ) && (pBitMapPixel == _bitmapPixels))
		{
			_bitmapFileHeader.bfType = 0x4D42;
			_bitmapFileHeader.bfSize = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + _BitMapPixelCnt;
			_bitmapFileHeader.bfReserved1 = 0x0000;
			_bitmapFileHeader.bfReserved2 = 0x0000;
			_bitmapFileHeader.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);

			_bitmapInfoHeader.biSize = sizeof (BITMAPINFOHEADER);		//  DWORD
			_bitmapInfoHeader.biWidth = Width;							//  LONG  
			_bitmapInfoHeader.biHeight = Height;						//  LONG  
			_bitmapInfoHeader.biPlanes = 1;								//	WORD  
			_bitmapInfoHeader.biBitCount = 24;							//	WORD  
			_bitmapInfoHeader.biCompression = 0;						//  DWORD 
			_bitmapInfoHeader.biSizeImage = _BitMapPixelCnt;			//  DWORD 
			_bitmapInfoHeader.biXPelsPerMeter = 0x0B12;					//  LONG  
			_bitmapInfoHeader.biYPelsPerMeter =  0x0B12;				//	LONG  
			_bitmapInfoHeader.biClrUsed = 0;							//	DWORD 
			_bitmapInfoHeader.biClrImportant = 0;						//	DWORD 
		}
	}
	return;
}

bool USBitMap::SaveAsFile(TCHAR *Directory)
{
	bool rc = false;

	if (IsValid())
	{

		std::wstring filename(Directory);
		filename += _DicomRef;
		filename += L".bmp";

		std::ofstream bitmapfile;
		bitmapfile.open (filename, std::ios::out | std::ios::trunc | std::ios::binary); 

		if (bitmapfile.is_open()) 
		{
			BYTE *pHeader = (BYTE *)&_bitmapFileHeader;
			bitmapfile.write((const char *)pHeader, sizeof (BITMAPFILEHEADER));
			pHeader = (BYTE *)&_bitmapInfoHeader;
			bitmapfile.write((const char *)pHeader, sizeof (BITMAPINFOHEADER));

			bitmapfile.write((const char *)_bitmapPixels, _BitMapPixelCnt);
			bitmapfile.close();

			rc = true;
		}
	}
	return rc;
}


bool USBitMap::SaveAsFile(std::wstring &directory)
{
	bool rc = false;

	if (IsValid())
	{

		std::wstring filename(directory);
		filename += _DicomRef;
		filename += L".bmp";

		std::ofstream bitmapfile;
		bitmapfile.open (filename, std::ios::out | std::ios::trunc | std::ios::binary); 

		if (bitmapfile.is_open()) 
		{
			BYTE *pHeader = (BYTE *)&_bitmapFileHeader;
			bitmapfile.write((const char *)pHeader, sizeof (BITMAPFILEHEADER));
			pHeader = (BYTE *)&_bitmapInfoHeader;
			bitmapfile.write((const char *)pHeader, sizeof (BITMAPINFOHEADER));

			bitmapfile.write((const char *)_bitmapPixels, _BitMapPixelCnt);
			bitmapfile.close();

			rc = true;
		}
	}
	return rc;
}



//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------

